﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;
using FacebookWrapper;
using FacebookWrapper.ObjectModel;



namespace B12_Ex01_Guy_066473471_Erez_021616735.FacebookApplicationLogic
{   
 
    public sealed class FacebookApplication2
    {
        private static FacebookApplication2 s_Instance = null;
        private static object s_LockObj = new Object();

        private LoginResult result = null;
        public User LoggedInUser { get; set; }
        public String AccessToken { get; set; }

        private Thread SaveToFileThread;

        /// <summary>
        /// 
        /// singelton
        /// </summary>
        /// <param name="i_LoggedInUser"></param>
        private FacebookApplication2()
        {
            
        }
        public static FacebookApplication2 Instance
        {
            get
            {
                if (s_Instance == null)
                {
                    lock (s_LockObj)
                    {
                        if (s_Instance == null)
                        {
                            s_Instance = new FacebookApplication2();
                        }
                    }
                }

                return s_Instance;
            }
        }

        public bool LooIn()
        {
            bool retVal = false;
            result = FacebookService.Login("322549387800673",
              "user_about_me", "friends_about_me", "publish_stream", "user_events", "read_stream",
              "user_status", "friends_birthday", "friends_location", "friends_checkins", "friends_photos", // this is instead of the 'user_checkins' permission, as desricbed here: http://developers.facebook.com/bugs/170251059758531
              "user_activities", "friends_activities", "user_birthday", "friends_birthday", "user_checkins"
              , "friends_events", "user_hometown", "friends_hometown",
              "user_interests", "friends_interests", "user_likes", "friends_likes", "user_location", "friends_location", "user_notes", "friends_notes",
              "user_online_presence", "friends_status");
            // "user_religion_politics","friends_religion_politics","user_status",  "friends_videos","user_website", "friends_website",
            //, "friends_likes","user_photos", "user_work_history", "friends_work_history", 
            //"email","read_friendlists", "read_insights", "read_mailbox", "read_requests", "read_stream", "xmpp_login"
            //"create_event","user_relationship_details","friends_relationship_details",
            //"rsvp_event","friends_photos","user_relationships", "friends_relationships",
            //"sms","user_videos",,"user_education_history", "friends_education_history"
            //"publish_checkins","user_groups" , "friends_groups", "friends_photos",
            //"manage_friendlists","friends_online_presence","user_photo_video_tags", "friends_photo_video_tags","user_photos", 
            //"manage_pages",

            //"offline_access"

            if (string.IsNullOrEmpty(result.ErrorMessage) && result.LoggedInUser != null)
            {
                retVal = true;
                init();
            }
            else
            {
                MessageBox.Show(result.ErrorMessage);
            }

            return retVal;
        }

        public bool Connect(string i_AccessToken)
        {
            bool retVal = false; 
            result = FacebookService.Connect(i_AccessToken);

            if (string.IsNullOrEmpty(result.ErrorMessage) && result.LoggedInUser != null)
            {
                retVal = true;
                init();
            }
            else
            {
                MessageBox.Show(result.ErrorMessage);
            }

            return retVal;
        }

       
        /// <summary>
        /// This function requests all friends from  API FACEBOOK 
        /// </summary>
        /// <returns>return list of friends from type User</returns>
        public List<User> getFriends()
        {
            return LoggedInUser.Friends.ToList();
        }

        /// <summary>
        /// This function requests all friends from  API FACEBOOK 
        /// </summary>
        /// <returns>return list of Male friends from type User</returns>
        public List<User> getMaleFriends()
        {
            List<User> maleFriends = new List<User>();

            foreach (User friend in getFriends())
            {
                if (friend.Gender == FacebookWrapper.ObjectModel.User.eGender.male)
                {
                    maleFriends.Add(friend);
                }
            }

            return maleFriends;
        }

        /// <summary>
        /// This function requests all friends from  API FACEBOOK 
        /// </summary>
        /// <returns>return list of Female friends from type User</returns>
        public List<User> getFemaleFriends()
        {
            List<User> maleFriends = new List<User>();

            foreach (User friend in getFriends())
            {
                if (friend.Gender == FacebookWrapper.ObjectModel.User.eGender.female)
                    maleFriends.Add(friend);
            }

            return maleFriends;
        }

        /// <summary>
        /// This function requests all friends from  API FACEBOOK 
        /// //key = id,val = user name
        /// </summary>
        /// <returns>return Dictionary of friends from type User</returns>
        public Dictionary<String, String> getFriendsName()
        {
            Dictionary<String, String> namesFrinds = new Dictionary<String, String>();

            foreach (User friend in LoggedInUser.Friends)
            {
                namesFrinds.Add(friend.Id, friend.Name);
            }

            return namesFrinds;
        }

        /// <summary>
        /// This function will requests all the friends of Facebook, 
        /// and compare with a list of friends that she kept on file from previous wheelbarrows
        /// </summary>
        /// <returns>return a list of all members of your ex friends</returns>
        public List<String> getExFriendsNames()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<String>));
            TextReader textReader;
            List<String> saveFrindes;
            List<String> ExFriends = null;

            try
            {
                textReader = new StreamReader(LoggedInUser.Id + ".xml");
                saveFrindes = (List<String>)serializer.Deserialize(textReader);
                textReader.Close();
            }
            catch (IOException ex)
            {
                return ExFriends;
            }

            ExFriends = new List<string>();
            var currFrindes = this.getFriendsName();

            foreach (String nameNreind in saveFrindes)
            {
                if (currFrindes.ContainsValue(nameNreind) == false)
                {
                    ExFriends.Add(nameNreind);
                }
            }

            return ExFriends;
        }

        private void init()
        {
            LoggedInUser = result.LoggedInUser;
            AccessToken = result.AccessToken;
            saveingFriendsInFileAsync();
        }
        private void saveingFriendsInFileAsync()
        {
            SaveToFileThread = new Thread(new ThreadStart(this.saveingFriendsInFile));
            SaveToFileThread.Start();
        }

        /// <summary>
        /// This function will save all your friends on file in the file name will be your ID
        /// </summary>
        private void saveingFriendsInFile()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<String>));
            TextReader textReader;
            List<String> saveFrindes;

            try
            {
                textReader = new StreamReader(LoggedInUser.Id + ".xml");
                saveFrindes = (List<String>)serializer.Deserialize(textReader);
                textReader.Close();
            }
            catch (IOException ex)
            {
                saveFrindes = new List<String>();
            }

            var currFrindes = this.getFriendsName();

            foreach (KeyValuePair<string, string> freind in currFrindes)
            {
                if (saveFrindes.Contains(freind.Value) == false)
                {
                    saveFrindes.Add(freind.Value);
                }
            }

            TextWriter textWriter = new StreamWriter(LoggedInUser.Id + ".xml");
            serializer.Serialize(textWriter, saveFrindes);
            textWriter.Close();
        }
    }

   
   
}
